/*
 * .h
 */

#ifndef ARRAY_CLASS
#define ARRAY_CLASS

#include <iostream>
#include <cstdlib>
using namespace std;

#ifndef NULL
const int NULL = 0;
#endif

enum ErrorType
{
	invalidArraySize, memoryAllocationError, indexOutOfRange	
};

char *errorMsg[] = 
{
	"Invalid array size",
	"Memory allocation error",
	"Invalid index: "
};

template < class T >
class Array
{
	private :
		T * alist;
		int size;
		void Error(ErrorType error, int badIndex = 0) const;
	public:
		Array(int sz = 50);
		Array(const Array < T > & A);
		~Array(void);
		Array < T > & operator = (const Array < T > & rhs);

		T & operator[] (int i);
		operator T * (void) const;
		int ListSize(void) const;
		void Resize(int sz);
};

/*
 * define implement 
 */

template < class T >
void Array < T >::Error(ErrorType error, int badIndex) const
{
	cout << errorMsg[error];
	if (error == indexOutOfRange)
		cout << badIndex;
	cout << endl;
	exit(1);
}

template < class T >
Array < T >::Array(int sz)
{
	if (sz <= 0)
		Error(invalidArraySize);
	size = sz;
	alist = new T[size];
	if (alist == NULL)
		Error(memoryallocationError);
}

tmeplate < class T >
Array < T > :: ~Array(void)
{
	delete [] alist;
}

template < class T >
Array < T > :: Array(const Array < T > & x)
{
	int n = x.size;
	size = n;
	alist = new T[n];
	if (alist == NULL)
		Error(memoryAllocationError);
	T * srcptr = x.alist;
	T * destptr = alist;
	while (n--)
		*destptr++ = *srcptr++;
}

template < class T >
Array < T >& Array < T > :: operator = (const Array < T > & rhs)
{
	int n = rhs.size;
	if (size != n) {
		delete [] alist;
		alist = new T[n];
		if (alist == NULL)
			Error (memoryAllocationError);
		size = n;
	}

	T * destptr = alist;
	T * srcptr  = rhs.alist;
	while (n--)
		*destptr++ = *srcptr++;

	return *this;
}

template < class T >
T & Array < T >::operator [] (int n)
{
	if (n < 0 || n > size -1 )
		Error(indexOutOfRange, n);

	return alist[n];
}

template < class T >
Array < T > ::operator T* (void) const
{
	return alist;
}

template < class T >
int Array< T > :: ListSize(void) const
{
	return size;
}

template < class T >
void Array < T > :: Resize(int sz)
{
	if (sz <= 0)
		Error(invalidArraySize);
	if (sz == size)
		return ;

	T * newlist = new T[sz];
	if (newlist == NULL)
		Error(memoryAllocationError);

	int n = (sz <= size) ? sz : size;
	T * srcptr = alist;
	T * destptr = newlist;
	while (n--)
		*destptr++ = *srcptr++;
	delete [] alist;
	alist = newlist;
	size = sz;
}

#endif		/* ARRAY_CLASS */


/* 
 * .cpp
 * 
 * application 
 */

#include <iomanip>

using namespace std;

int main()
{
	Array < int > a(10);
	int n;
	int primecount = 0, i, j;

	cout << "Enter a value >= 2 as upper limit for prime numbers: ";
	cin >> n;

	A[primecount++] = 2;
	for (i = 3; i < n; i++) {
		if (primecount == A.ListSize())
			A.Resize(primecount + 10);
		if (i % 2 == 0)
			continue;
		j = 3;
		while (j <= i / 2 && i % j != 0)
			j += 2;
		if (j > i / 2)
			A[primecount++] = i;
	}

	for ( i = 0; i < primecount; i++) {
		cout << setw(5) << A[i];
		if (i( i+1) % 10 == 0)
			cout << endl;
	}

	cout << endl;
}